import json
from solcx import compile_standard, install_solc
from web3 import Web3

# 安装指定版本的Solidity编译器
install_solc('0.8.0')

# 读取Solidity合约文件
with open('src/SoftwareSecurity.sol', 'r', encoding='utf-8') as file:
    software_security_sol = file.read()

# 编译合约
compiled_sol = compile_standard({
    "language": "Solidity",
    "sources": {
        "SoftwareSecurity.sol": {
            "content": software_security_sol
        }
    },
    "settings": {
        "outputSelection": {
            "*": {
                "*": ["abi", "metadata", "evm.bytecode", "evm.sourceMap"]
            }
        }
    }
}, solc_version='0.8.0')

# 获取字节码和ABI
bytecode = compiled_sol['contracts']['SoftwareSecurity.sol']['SoftwareSecurity']['evm']['bytecode']['object']
abi = compiled_sol['contracts']['SoftwareSecurity.sol']['SoftwareSecurity']['abi']

# Ganache 区块链连接
ganache_url = "http://127.0.0.1:8545"
web3 = Web3(Web3.HTTPProvider(ganache_url))

# 确保连接成功
if not web3.is_connected():
    raise Exception("Unable to connect to Ganache")

# 设置默认账户
web3.eth.default_account = web3.eth.accounts[0]

# 部署合约
SoftwareSecurity = web3.eth.contract(abi=abi, bytecode=bytecode)
tx_hash = SoftwareSecurity.constructor().transact()
tx_receipt = web3.eth.wait_for_transaction_receipt(tx_hash)

print(f"Contract deployed at address: {tx_receipt.contractAddress}")

# 与合约交互
contract_address = tx_receipt.contractAddress
contract = web3.eth.contract(address=contract_address, abi=abi)

# 上传新的记录
def upload(cid, name, dep_cids, dep_poisons, time, version, user):
    tx_hash = contract.functions.upload(cid, name, dep_cids, dep_poisons, time, version, user).transact()
    receipt = web3.eth.wait_for_transaction_receipt(tx_hash)
    return receipt

# 获取信息
def get_info(cid):
    return contract.functions.getInfo(cid).call()

# 搜索 Poison
def search_poison(cid):
    tx_hash = contract.functions.searchPoison(cid).transact()
    receipt = web3.eth.wait_for_transaction_receipt(tx_hash)
    return receipt

# 更新 Poison
def update_poison(cid, poison):
    tx_hash = contract.functions.update(cid, poison).transact()
    receipt = web3.eth.wait_for_transaction_receipt(tx_hash)
    return receipt


if __name__ == "__main__":
    # 上传记录示例
    dep_cids = ["CID1", "CID2"]
    dep_poisons = ["CVE2024-123", "CVE2024-124"]
    receipt = upload("CID123", "filename", dep_cids, dep_poisons, "2024.1.1", "1.1.1", "bob")
    print(f"Upload Receipt: {receipt}")

    # 获取信息示例
    info = get_info("CID123")
    print(f"Info: {info}")

    # 搜索 Poison 示例
    receipt = search_poison("CID123")
    print(f"Search Poison Receipt: {receipt}")

    # 更新 Poison 示例
    receipt = update_poison("CID123", "CVE-123")
    print(f"Update Poison Receipt: {receipt}")

    # 获取更新后信息
    updated_info = get_info("CID123")
    print(f"Updated Info: {updated_info}")
